package org.sith.taskrunner.ejb.interceptors;

import org.sith.taskrunner.api.user.Role;
import org.sith.taskrunner.ejb.UserThreadKeeper;
import org.sith.taskrunner.ejb.annotations.AllowedRoles;
import org.sith.taskrunner.ejb.exceptions.PermissionsException;

import javax.interceptor.AroundInvoke;
import javax.interceptor.InvocationContext;
import java.util.Arrays;
import java.util.List;

public class PermissionsChecker {

    @AroundInvoke
    public Object checkPermissions(InvocationContext invocationContext) throws Exception {
        AllowedRoles annotation = getAnnotation(invocationContext);

        if (annotation != null) {
            return checkRole(invocationContext, annotation);
        } else {
            return invocationContext.proceed();
        }
    }


    private AllowedRoles getAnnotation(InvocationContext invocationContext) {
        AllowedRoles annotation = invocationContext.getTarget().getClass().getAnnotation(AllowedRoles.class);
        if (annotation == null) {
            annotation = invocationContext.getMethod().getAnnotation(AllowedRoles.class);
        }
        return annotation;
    }

    private Object checkRole(InvocationContext invocationContext, AllowedRoles annotation) throws Exception {
        Role[] roles = annotation.value();
        List<Role> roleList = Arrays.asList(roles);
        Role role = UserThreadKeeper.getThreadUser().getRole();
        if (Role.SYSTEM.equals(role)) {
            return invocationContext.proceed();
        } else if (roleList.contains(role)) {
            return invocationContext.proceed();
        } else {
            throw new PermissionsException();
        }
    }

}
